<?php
/**
 * Master控制器
 *
 * PHP version 5
 *
 * @package   Ecga
 * @author    sunfengming <sunfengming@ec3s.com>
 * @copyright 2010 Xingchangxinda Inc.
 * @version   SVN: $Id$
 */
namespace Project\Apps\Ecga\Controllers;


use \Project\Apps\Ecga\Models\UserModelException;
use \Project\Apps\Ecga\Library\AdminAuth;
use \Project\Apps\Ecga\Models\Users;
use \Project\Apps\Ecga\Models\Projects;
use \Project\Apps\Ecga\Controllers\Abstraction\EcgaController;
use \Framework\System\Helper\HttpResponse;
use \Framework\System\Helper\HttpRequest;
use \Framework\Controller\ControllerException;
use \Framework\Mapper\FieldException;
use \Framework\System\Helper\Mail;

/**
 * Master控制器
 *
 * PHP version 5
 *
 * @package   Ecga
 * @author    sunfengming <sunfengming@ec3s.com>
 * @copyright 2010 Xingchangxinda Inc.
 * @version   Release: <0.1>
 */
class Master extends EcgaController
{
    /**
     * 默认Action
     *
     * @param HttpRequest $request request
     *
     * @return void
     */
    public static function show($request)
    {
        $page = self::createPage();
        $page->setTitle('管理员列表');
        $projectModel = model('Projects');
        $pageNo = $request->get('page', 'int', 1);
        $projectModel = model('Projects');
        $userList = self::createDataList(Users::getPageQuery())
            ->setCurrentPage($pageNo)
            ->orderBy('id', 'desc');

        $page->assign('list', $userList);
        $page->assign('uri', $request->uri);
        $page->assign('projectOptions', $projectModel->getProjectOptions());
        $page->assign('authOptions', self::_getAuthOptions());
        HttpResponse::output($page->render('userlist'));
    }

    /**
     * 获取操作权限列表
     *
     * @return array 权限列表
     * @author sunfengming
     */
    private static function _getAuthOptions()
    {
        $authArray = AdminAuth::parseAuthFile();
        $result = array();
        foreach ($authArray as $key => $titles) {
            $result[$titles[0]][$key] = $titles[1];
        }
        return $result;
    }

    /**
     * 添加管理员
     *
     * @param HttpRequest $request HttpRequest对象
     *
     * @return void
     * @author sunfengming
     */
    public static function add($request)
    {
        $userModel = model('Users');
        $projectModel = model('Projects');
        $authOptions = self::_getAuthOptions();
        $authOptions = reset($authOptions);
        $page = self::createPage();
        $page->setTitle('添加管理员');
        $page->assign('authOptions', $authOptions);
        $page->assign('formHash', self::generateFormHash('doAdd'));
        $page->assign('projectOptions', $projectModel->getOptions());
        HttpResponse::output($page->render('userdetail'));
    }

    /**
     * 处理管理员添加表单提交
     *
     * @param HttpRequest $request HttpRequest对象
     *
     * @return void
     * @author sunfengming
     * @throws FieldException
     */
    public static function doAdd($request)
    {
        $formHash = $request->post('formHash', 'string');
        if (!self::validateFormHash('doAdd', $formHash)) {
            //self::message('对不起，表单已过期，请您重新操作！', 'warning', './master.php?a=show');
        }

        $userModel = model('Users');
        $userProjectPrivsModel = model('UserProjectPrivs');
        $data = self::_getFormData($request);
        $data = array_merge($data, $userModel->createPassword());
        $unEncryptPassword = $data['unEncryptPassword'];
        unset($data['unEncryptPassword']);
        $user = $userModel->create();
        try {
            $newUser = self::_save($user, $data);
	       	foreach ($data['allow'] as $key => $allow) {
	       		$privs = null;
	       		$privs = $userProjectPrivsModel->create();
	       		self::_savePrivs(
	       			$privs, 
	       			array(
	       				'userId' => $newUser->id,
	       				'projectId' => $key,
	       				'privs' => serialize($allow)
	       			)
	       		);
	       	}
        } catch (ControllerException $e) {
        	if ($newUser) {
        		$newPrivs = $userProjectPrivsModel->getByUserId($userUser->id);
        		if ($newPrivs) {
        			foreach ($newPrivs as $value) {
        				$value->delete();
        			}
        		}
        		$newUser->delete();
        	}
            self::message($e->getMessage(), 'warning');
            self::add($request);
            return;
        }
        //邮件发送
        $loginUrl = $request->scheme . $_SERVER['HTTP_HOST'];
        $mailContent = "尊敬的用户：<br /> " .
            "   欢迎您使用ECGA数据挖掘系统。" .
            "本系统的登录地址是：$loginUrl ，登录时请使用您的邮箱地址登录。<br />" .
            "邮箱地址：$user->userEmail ，用户名称：$user->userName ，密码：$unEncryptPassword" .
            "<br /> " .
            "请在初次登录后修改您的密码，确保使用安全。<br />" .
            "由于本系统涉及到公司内部敏感信息，请你妥善保管您的用户密码，" .
            "以免造成不必要的损失。 <br />" .
            "祝您使用愉快。 <br />" .
            "这封邮件由系统自动生成，请勿回复。 <br />" ;
        Mail::addToQueue(
            $user->userEmail,
            'ECGA数据挖掘系统新用户信息',
            $mailContent,
            Mail::PRI_HIGH,
            null,
            0
        );
        self::message(
            sprintf(
                '您已成功添加了管理员“%s”，登录密码已发送到“%s”。',
                $data['userName'], $data['userEmail']
            ), 'notice', './master.php?a=show'
        );
    }

    /**
     * 编辑用户权限
     *
     * @param HttpRequest $request HttpRequest Instance
     *
     * @throws ControllerException
     *
     * @return void
     * @author sunfengming
     */
    public static function edit($request)
    {
        $userModel = model('Users');
        $id = $request->get('id', 'int');
        $user = $userModel->get($id);
        if ($user === null) {
            throw new ControllerException('对不起，您要编辑的管理员不存在！');
        }
        if (1 == $user->id) {
            throw new ControllerException('对不起，此管理员为创始人，不能编辑！');
        }
        $projectModel = model('Projects');
        $authOptions = self::_getAuthOptions();
        $authOptions = reset($authOptions);
        $userAuths = model('UserProjectPrivs')->getByUserIdToArray($id);
        $page = self::createPage();
        $page->setTitle('修改管理员');
        $page->assign('authOptions', $authOptions);
        $page->assign('data', $user);
        $page->assign('projectOptions', $projectModel->getOptions());
        $page->assign('id', $id);
        $page->assign('userAuths', $userAuths);
        $page->assign('formHash', self::generateFormHash('doEdit'));
        HttpResponse::output($page->render('userdetail'));
    }

    /**
     * ORM修改用户权限
     *
     * @param HttpRequest $request HttpRequest Instance
     *
     * @throws ControllerException
     *
     * @return void
     * @author sunfengming
     */
    public static function doEdit($request)
    {
        $id = $request->post('id', 'int');
        $formHash = $request->post('formHash', 'string');
        if (!self::validateFormHash('doEdit', $formHash)) {
            //self::message('对不起，表单已过期，请您重新操作！', 'warning', './master.php?a=show');
        }

        $userModel = model('Users');
        $data = self::_getFormData($request);
        $user = $userModel->get($id);
        if ($user === null) {
            throw new ControllerException('对不起，您要编辑的管理员不存在！');
        }
        if (1 == $user->id) {
            throw new ControllerException('对不起，此管理员为创始人，不能编辑！');
        }
        try {
            self::_save($user, $data);
            $oldPrivs = model('UserProjectPrivs')->getByUserId($id);
            foreach ($oldPrivs as $value) {
            	$value->delete();
            }
	       	foreach ($data['allow'] as $key => $allow) {
	       		$privs = null;
	       		$privs = model('UserProjectPrivs')->create();
	       		self::_savePrivs(
	       			$privs, 
	       			array(
	       				'userId' => $id,
	       				'projectId' => $key,
	       				'privs' => serialize($allow)
	       			)
	       		);
	       	}
        } catch (ControllerException $e) {
            self::message($e->getMessage(), 'warning');
            self::add($request);
            return;
        }

        self::message(
            sprintf(
                '您已成功修改了管理员“%s”的信息。',
                $data['userName']
            ), 'notice', './master.php?a=show'
        );
    }

    /**
     * 保存管理员信息
     *
     * @param Entity $entity 管理员实体
     * @param array  $data   需要保存的管理员信息
     *
     * @return void
     * @throws ControllerException FieldException
     * @author sunfengming
     */
    private static function _save ($entity, $data)
    {
        try {
            return $entity->setAttributes($data)->save();
        } catch (FieldException $e) {
            switch ($e->getCode()) {
            case FieldException::BLANK_VALUE :
                if ($e->field == 'userName') {
                    $message = '对不起，管理员名称不能为空。';
                } elseif ($e->field == 'userEmail') {
                    $message = '对不起，管理员邮箱不能为空。';
                } elseif ($e->field == 'allowProjects') {
                    $message = '对不起，可管理项目不得为空。';
                } else {
                    throw $e;
                }
                break;
            case FieldException::UNIQUE_VALUE :
                if ($e->field == 'siteId,userName') {
                    $message = '对不起，管理员名称已存在。';
                } elseif ($e->field == 'siteId,userEmail') {
                    $message = '对不起，管理员邮箱已存在。';
                } else {
                    throw $e;
                }
                break;
            case FieldException::INVALUD_VALUE :
                if ($e->field == 'userEmail') {
                    $message = '对不起，管理员邮箱格式不正确。';
                } else {
                    throw $e;
                }
                break;
            default:
                throw $e;
            }
            throw new ControllerException($message);
        }
    }
    
    /**
     * 保存权限
     * 
     * @param object $entity 实体
     * @param array  $data   数据
     * 
     * @throws FieldException
     * @throws ControllerException
     * 
     * @return void
     */
    private static function _savePrivs($entity, $data)
    {
    	try {
    		$entity->setAttributes($data)->save();
    	} catch (FieldException $e) {
    		$blankValueMessages = array(
    			'userId' => '用户ID不能为空!',
    			'projectId' => '项目ID不能为空!',
    			'privs' => '权限不能为空'
    		);
    		switch ($e->getCode()) {
    		case FieldException::BLANK_VALUE : 
    		case FieldException::NULL_VALUE :
    			$message = $blankValueMessages[$e->field];
    			break;
    		default:
    			throw $e;
    		}
    		throw new ControllerException($message);
    	}
    }
    
    /**
     * 删除管理员
     *
     * @param HttpRequest $request HttpRequest对象
     *
     * @return void
     * @author sunfengming
     */
    public static function remove($request)
    {
        $userModel = model('Users');
        $id = $request->post('id', 'int');
        $user = $userModel->get($id);
        if ($user === null) {
            HttpResponse::jsonWarning('对不起，您要删除的管理员不存在！');
            return;
        }
        $userName = $user->userName;
        try {
            self::_drop($user);
        } catch (\Framework\Mapper\ModelException $e) {
            HttpResponse::jsonWarning($e->getMessage());
        }
    }

    /**
     * 批量删除管理员
     *
     * @param HttpRequest $request HttpRequest对象
     *
     * @return void
     * @author sunfengming
     */
    public static function batchRemove($request)
    {
        $userModel = model('Users');
        $ids = $request->post('id', 'array');
        foreach ($ids as $id) {
            $user = $userModel->get($id);
            if ($user === null) {
                continue;
            }
            $userName = $user->userName;
            try {
                self::_drop($user);
            } catch (ControllerException $e) {
                self::message($e->getMessage(), 'warning');
                continue;
            }
            self::message(sprintf('您已成功删除了管理员“%s”。', $userName));
        }
        HttpResponse::redirect($request->referer);
    }

    /**
     * 删除管理员
     *
     * @param Entity $user 管理员对象
     *
     * @return void
     * @throws ControllerException
     * @author sunfengming
     */
    private static function _drop($user)
    {
       	$privs = model('UserProjectPrivs')->getByUserId($user->id);
        if ($privs) {
           	foreach ($privs as $value) {
       			$value->delete();
       		}
        }
        $user->delete();
    }

    /**
     * 重置管理员密码
     *
     * @param HttpRequest $request HttpRequest对象
     *
     * @return void
     * @author sunfengming
     */
    public static function resetPassword($request)
    {
        $userModel = model('Users');
        $id = $request->get('id', 'int');
        $user = $userModel->get($id);
        if ($user === null) {
            self::message('对不起，您操作的管理员不存在！', 'warning', 'master.php?a=show');
            return;
        }
        /**
         * 生成随机6位密码和4位扰码 并发送邮件
         */
        $salt        = substr(uniqid(), -4);
        $password    = substr(uniqid(), -6);
        //存入md5加密后的六位密码和四位扰码字符串
        $md5Password = $userModel->encrypt($password, $salt);

        try {
            self::_save($user, array('password' => $md5Password, 'salt' => $salt));
        } catch (ControllerException $e) {
            HttpResponse::jsonWarning($e->getMessage());
            return;
        }
        //邮件发送
        Mail::addToQueue(
            $user->userEmail,
            'ECGA数据挖掘系统管理密码',
            "用户名：$user->userName , 密码：$password",
            Mail::PRI_HIGH,
            null,
            0
        );

        self::message(
            sprintf(
                '您已成功重置了管理员“%s”的密码，并已发送邮件提示。新密码为：' .
                $password,
                $user->userName
            ), 'notice', './master.php?a=show'
        );
    }


    /**
     * 得到表单数据
     *
     * @param HttpRequest $request HttpRequest对象
     * @param bool        $isEdit  是否是修改
     *
     * @return array
     * @author Blue5tar
     */
    private static function _getFormData($request, $isEdit = false)
    {
        $userProjectPrivs = $request->post('userProjectPrivs', 'array');
        if (empty($userProjectPrivs) || null === $userProjectPrivs) {
            throw new ControllerException('用户权限不得为空！');
        }
        $allowTables = array();
        foreach ($userProjectPrivs as $value) {
            $tmp = explode('-', $value);
            $allowTables[$tmp[0]][] = $tmp[1];
        }
        if (!$isEdit) {
            return array(
                'userName'  => $request->post('userName', 'string'),
                'userEmail' => $request->post('userEmail', 'string'),
                'allow'   => $allowTables
            );
        } else {
            return array(
                'allow' => $allowTables
            );
        }
    }
}